package com.demon.androidbasic.base

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.inputmethod.InputMethodManager
import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.demon.androidbasic.action.*
import com.demon.logger.Logger
import com.demon.net.AppResponse
import com.hjq.http.listener.OnHttpListener
import okhttp3.Call
import java.util.*
import kotlin.system.exitProcess

/**
 * author : Android 轮子哥
 * github : https://github.com/getActivity/AndroidProject
 * time   : 2018/10/18
 * desc   : Activity 基类
 */
abstract class BaseBindActivity<T : ViewBinding> : AppCompatActivity(), ActivityAction, NoDoubleClickAction,
    HandlerAction, BundleAction, ToastAction {

    protected lateinit var binding: T
    protected lateinit var inflater: LayoutInflater
    override lateinit var activity: BaseBindActivity<T>

    /**
     * startActivityForResult 方法优化
     */
    private var mActivityCallback: OnActivityCallback? = null
    private var mActivityRequestCode = 0

    override var clickTime = 0L

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        try {
            initActivity()
        } catch (e: Exception) {
            e.printStackTrace()
            toast("打开失败")
            finish()
            exitProcess(0)
        }
    }

    private fun initActivity() {
        activity = this
        initLayout()
        initView()
        initData()
    }

    /**
     * 初始化布局
     */
    @CallSuper
    protected open fun initLayout() {
        inflater = layoutInflater
        initBind()
        setContentView(binding.root)
        initSoftKeyboard()
    }

    /**
     * 初始化绑定
     */
    protected abstract fun initBind()

    /**
     * 初始化控件
     */
    protected abstract fun initView()

    /**
     * 初始化数据
     */
    protected abstract fun initData()

    /**
     * 初始化软键盘
     */
    protected fun initSoftKeyboard() {
        // 点击外部隐藏软键盘，提升用户体验
        contentView.setOnClickListener { v: View? -> hideSoftKeyboard() }
    }

    protected var isPaused = false
        private set

    override fun onResume() {
        super.onResume()
        isPaused = false
    }

    override fun onPause() {
        super.onPause()
        isPaused = true
    }

    override fun onDestroy() {
        removeCallbacks()
        super.onDestroy()
        Logger.i("Lifecycle", "$this onDestroy")
    }

    override fun finish() {
        hideSoftKeyboard()
        super.finish()
    }

    /**
     * 如果当前的 Activity（singleTop 启动模式） 被复用时会回调
     */
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        // 设置为当前的 Intent，避免 Activity 被杀死后重启 Intent 还是最原先的那个
        setIntent(intent)
    }

    override val bundle: Bundle?
        get() {
            return intent.extras
        }

    /**
     * 和 setContentView 对应的方法
     */
    val contentView: ViewGroup
        get() = findViewById(Window.ID_ANDROID_CONTENT)

    override val myContext: Context
        get() {
            return this
        }

    override fun startActivity(intent: Intent) {
        super<AppCompatActivity>.startActivity(intent)
    }

    fun startActivityForResult(clazz: Class<out Activity?>, callback: OnActivityCallback?) {
        startActivityForResult(Intent(this, clazz), null, callback)
    }

    fun startActivityForResult(
        clazz: Class<out Activity>, args: Bundle, callback: OnActivityCallback
    ) {
        val intent = Intent(this, clazz)
        intent.putExtras(args)
        startActivityForResult(intent, callback)
    }

    fun startActivityForResult(intent: Intent, callback: OnActivityCallback?) {
        startActivityForResult(intent, null, callback)
    }

    fun startActivityForResult(intent: Intent, options: Bundle?, callback: OnActivityCallback?) {
        // 回调还没有结束，所以不能再次调用此方法，这个方法只适合一对一回调，其他需求请使用原生的方法实现
        if (mActivityCallback == null) {
            mActivityCallback = callback
            // 随机生成请求码，这个请求码必须在 2 的 16 次幂以内，也就是 0 - 65535
            mActivityRequestCode = Random().nextInt(Math.pow(2.0, 16.0).toInt())
            startActivityForResult(intent, mActivityRequestCode, options)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (mActivityCallback != null && mActivityRequestCode == requestCode) {
            mActivityCallback!!.onActivityResult(resultCode, data)
            mActivityCallback = null
        } else {
            super.onActivityResult(requestCode, resultCode, data)
        }
    }

    override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) {
        hideSoftKeyboard()
        // 查看源码得知 startActivity 最终也会调用 startActivityForResult
        try {
            super.startActivityForResult(intent, requestCode, options)
        } catch (e: Exception) {
            toast("打开失败")
            e.printStackTrace()
        }
    }

    /**
     * 隐藏软键盘
     */
    private fun hideSoftKeyboard() {
        // 隐藏软键盘，避免软键盘引发的内存泄露
        val view = currentFocus
        if (view != null) {
            val manager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
            if (manager != null && manager.isActive(view)) {
                manager.hideSoftInputFromWindow(
                    view.windowToken,
                    InputMethodManager.HIDE_NOT_ALWAYS
                )
            }
        }
    }

    open val onHttpListener: OnHttpListener<AppResponse<*>?>
        get() {
            return object : OnHttpListener<AppResponse<*>?> {

                override fun onStart(call: Call) {

                }

                override fun onSucceed(result: AppResponse<*>?) {
                    if (result is AppResponse<*> && "成功" != result.getResponseMessage()) {
                        toast(result.getResponseMessage())
                    }
                }

                override fun onFail(e: Exception?) {
                    toast(e?.message)
                }

                override fun onEnd(call: Call) {

                }
            }
        }

    interface OnActivityCallback {
        /**
         * 结果回调
         *
         * @param resultCode 结果码
         * @param data       数据
         */
        fun onActivityResult(resultCode: Int, data: Intent?)
    }
}